import { ApiProperty, getSchemaPath } from "@nestjs/swagger";
import { CrudValidationGroups } from "@nestjsx/crud";
import { hashSync } from "bcryptjs";
import { IsBoolean, IsNumber, IsOptional, IsString } from "class-validator";
import { Feedback } from 'libs/db/entity/feedback.entity';
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { Area } from './area.entity';
import { BaseEntity } from "./base.entity";
import { UserLevelEnum } from './enum/user-level.enum';
import { Town } from './town.entity';
import { Village } from './village.entity';
import { Logger } from "./logger.entity";


const { CREATE, UPDATE } = CrudValidationGroups;


@Entity()
export class User extends BaseEntity {

  @ApiProperty({
    // description: '用户-(管理员)-主键',
    required: false
  })
  @PrimaryGeneratedColumn()
  id ?: number;
  // @Column()
  // villager: Villager.id

  @ApiProperty({
    example: '用户名称',
    description: '用户名称',
    required: true
  })
  @IsString({ always: true})
  @Column({
    type: "char",
    length: 255,
  })
  name: string

  @ApiProperty({
    example: '用户账号',
    description: '用户账号',
    required: true
  })
  @IsString({ always: true})
  @Column({
    type: "char",
    length: 255,
  })
  username: string

  @ApiProperty({
    example: '用户密码',
    description: '用户密码',
    required: true
  })
  @IsString({ always: true })
  @IsOptional({ groups: [UPDATE] })
  @Column({
    // type: 'text',
    select: false
  })
  password: string

  @ApiProperty({
    type: Number,
    description: '用户处理的反馈',
    required: false,
  })
  @OneToMany(() => Feedback, Feedback => Feedback.handler)
  feedbacks ?: Number [] | Feedback []
  
  @ApiProperty({
    example: 1,
    description: '用户级别',
    required: true,
    type: Number,
    enum: UserLevelEnum
  })
  @IsNumber({}, { always: true })
  @Column({
    type: "enum",
    enum: UserLevelEnum,
  })
  level: UserLevelEnum
  
  @ApiProperty({
    example: 1,
    description: '区级管理员 所属区',
    required: true,
    oneOf: [
      {
        type: 'Number',
      },
      {
        $ref: getSchemaPath(() => Village),
      },
    ],
  })
  @ManyToOne(
    () => Village,
    Village => Village.users,
    {
      eager: true,
    },
  )
  village: Number | Village;
  

  @ApiProperty({
    example: 1,
    description: '镇级管理员 所属镇',
    required: true,
    oneOf: [
      {
        type: 'Number',
      },
      {
        $ref: getSchemaPath(() => Town),
      },
    ],
  })
  @ManyToOne(
    () => Town,
    Town => Town.users,
    {
      eager: true,
    },
  )
  town: Number | Town;

  @ApiProperty({
    example: 1,
    description: '区级管理员 所属区',
    required: true,
    oneOf: [
      {
        type: 'Number',
      },
      {
        $ref: getSchemaPath(() => Area),
      },
    ],
  })
  @ManyToOne(
    () => Area,
    Area => Area.users,
    {
      eager: true,
    },
  )
  area: Number | Area;

  @ApiProperty({
    example: false,
    description: '是否密码加密 -> 是否初始化',
    required: false
  })
  @IsBoolean()
  @IsOptional()
  @Column({
    default: false
  })
  init: Boolean

  @OneToMany(() => Logger, Logger => Logger.user)
  logs: Logger []
  
  // @Column()
  // authority: Authority[]
  @BeforeInsert()
  @BeforeUpdate()
  insertAndUpdateDates() {
    if(!this.password) {
      // this.password = null
    } else {
      this.password = hashSync(this.password)
    }
  }
}